home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Information / CSMP Digest / volume 1 / csmp-v1-183.txt < prev    next >
Text File  |  1992-12-31  |  45KB  |  1,528 lines

  1. C.S.M.P. Digest             Thu, 15 Oct 92       Volume 1 : Issue 183
  2.  
  3. Today's Topics:
  4.  
  5.     Repeated GetCIcon/PlotCIcon calls
  6.     Powerbook Battery Question
  7.     Quick TCL gDesktop question
  8.     Smooth Animation
  9.     Using PostHighLevelEvents to send low level (KeyPressed) events
  10.     Radio buttons
  11.     menubar in dialogs
  12.  
  13.  
  14.  
  15. The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
  16.  
  17. The digest is a collection of article threads from the internet newsgroup
  18. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  19. regularly and want an archive of the discussions.  If you don't know what a
  20. newsgroup is, you probably don't have access to it.  Ask your systems
  21. administrator(s) for details.  (This means you can't post questions to the
  22. digest.)
  23.  
  24. Each issue of the digest contains one or more sets of articles (called
  25. threads), with each set corresponding to a 'discussion' of a particular
  26. subject.  The articles are not edited; all articles included in this digest
  27. are in their original posted form (as received by our news server at
  28. cs.uoregon.edu).  Article threads are not added to the digest until the last
  29. article added to the thread is at least one month old (this is to ensure that
  30. the thread is dead before adding it to the digest).  Article threads that
  31. consist of only one message are generally not included in the digest.
  32.  
  33. The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
  34. [128.223.8.8] in the directory /pub/mac/csmp-digest.  Be sure to read the
  35. file /pub/mac/csmp-digest/README before downloading any files.  The most
  36. recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
  37. directory /info-mac/digest/csmp.  If you don't have ftp capability, the sumex
  38. archive has a mail server; send a message with the text '$MACarch help' (no
  39. quotes) to LISTSERV@ricevm1.rice.edu for more information.
  40.  
  41. The digest is also available via email.  Just send a note saying that you
  42. want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
  43. automatically receive each new issue as it is created.  Sorry, back issues
  44. are not available through the mailing list.
  45.  
  46. Send administrative mail to mkelly@cs.uoregon.edu.
  47.  
  48.  
  49. -------------------------------------------------------
  50.  
  51. From: bagpipe@reed.edu!bagpipe.reed.edu!pcalahan (Patrick John Calahan)
  52. Subject: Repeated GetCIcon/PlotCIcon calls
  53. Date: 14 Jul 92 22:48:21 GMT
  54. Organization: Reed College, Portland, OR
  55.  
  56. I need to plot a fairly large number of color icons a very large number
  57. of times in my application.
  58.  
  59. IMV says that you shouldn't call PlotCICon before each GetCIcon because
  60. it overhead will build up in the resource map.  Makes sense to me...that  
  61. seems to be happenening when my system crashes after plotting some number  
  62. of icons...
  63.  
  64. I don't know what I should be doing to dispose of the data when I'm done
  65. plotting it.  I've tried DisposCIcon & ReleaseResource, and both together,
  66. but nothing seems to do much good...memory still gets filled up.
  67.  
  68. I just want to get rid of the things after I draw them...what do I do?
  69.  
  70. +++++++++++++++++++++++++++
  71.  
  72. From: mxmora@unix.SRI.COM (Matt Mora)
  73. Date: 15 Jul 92 15:48:56 GMT
  74. Organization: SRI International, Menlo Park, California
  75.  
  76. In article <m0m7vfN-000FO0C@bagpipe.reed.edu> bagpipe@reed.edu!bagpipe.reed.edu!pcalahan (Patrick John Calahan) writes:
  77.  
  78. >IMV says that you shouldn't call PlotCICon before each GetCIcon because
  79. >it overhead will build up in the resource map.  Makes sense to me...that  
  80. >seems to be happenening when my system crashes after plotting some number  
  81. >of icons...
  82.  
  83. >I don't know what I should be doing to dispose of the data when I'm done
  84. >plotting it.  I've tried DisposCIcon & ReleaseResource, and both together,
  85. >but nothing seems to do much good...memory still gets filled up.
  86.  
  87. >I just want to get rid of the things after I draw them...what do I do?
  88.  
  89. You could mark them purgeable. But I don't think that really works. I think
  90. there is a bug with cicns or something because I tried to get rid of the
  91. memory but it would still fill up the heap. I'm using ploticonid now
  92. (tech note #30x) and it works fine. 
  93.  
  94. What you might want to do is create a gworld and plot all the icons at
  95. once. Then blit them in via copybits as you need them. Depending on the
  96. amount of icons and pixdepth this might not be posible in your case.
  97.  
  98. Matt
  99.  
  100.  
  101.  
  102. - -- 
  103. ___________________________________________________________
  104. Matthew Mora                |   my Mac  Matt_Mora@sri.com
  105. SRI International           |  my unix  mxmora@unix.sri.com
  106. ___________________________________________________________
  107.  
  108. +++++++++++++++++++++++++++
  109.  
  110. From: ozma@kuhub.cc.ukans.edu
  111. Date: 16 Jul 92 23:41:46 CDT
  112. Organization: University of Kansas Academic Computing Services
  113.  
  114. In article <36915@unix.SRI.COM>, mxmora@unix.SRI.COM (Matt Mora) writes:
  115. > In article <m0m7vfN-000FO0C@bagpipe.reed.edu> bagpipe@reed.edu!bagpipe.reed.edu!pcalahan (Patrick John Calahan) writes:
  116. >>IMV says that you shouldn't call PlotCICon before each GetCIcon because
  117. >>it overhead will build up in the resource map.  Makes sense to me...that  
  118. >>seems to be happenening when my system crashes after plotting some number  
  119. >>of icons...
  120.  
  121. > You could mark them purgeable. But I don't think that really works. I think
  122. > there is a bug with cicns or something because I tried to get rid of the
  123. > memory but it would still fill up the heap. I'm using ploticonid now
  124. > (tech note #30x) and it works fine. 
  125.  
  126. I believe ReleaseResource() after every PlotCIcon will do the trick.
  127.  
  128. john calhoun-
  129.  
  130.  
  131. +++++++++++++++++++++++++++
  132.  
  133. From: gluttony@reed.edu!gluttony.reed.edu!pcalahan (Patrick John Calahan)
  134. Date: 17 Jul 92 21:14:24 GMT
  135. Organization: Reed College, Portland, OR
  136.  
  137. In article <1992Jul16.234146.41639@kuhub.cc.ukans.edu>  
  138. ozma@kuhub.cc.ukans.edu writes:
  139.  
  140. > I believe ReleaseResource() after every PlotCIcon will do the trick.
  141. > john calhoun-
  142.  
  143. nope. like i said in the message, i had been using release resource but
  144. it still wasn't working.  i kludged my way around it by quitting the
  145. application after plotting a lot of icons (i only needed to see them for a
  146. while while the app is in development).  a more elegant solution remains 
  147. a mystery to me
  148.  
  149. +++++++++++++++++++++++++++
  150.  
  151. From: ozma@kuhub.cc.ukans.edu
  152. Date: 19 Jul 92 01:04:03 CDT
  153. Organization: University of Kansas Academic Computing Services
  154.  
  155. In article <m0m8zd3-0006ChC@gluttony.reed.edu>, gluttony@reed.edu!gluttony.reed.edu!pcalahan (Patrick John Calahan) writes:
  156. > In article <1992Jul16.234146.41639@kuhub.cc.ukans.edu>  
  157. > ozma@kuhub.cc.ukans.edu writes:
  158. >> I believe ReleaseResource() after every PlotCIcon will do the trick.
  159. >> john calhoun-
  160. > nope. like i said in the message, i had been using release resource but
  161. > it still wasn't working.  i kludged my way around it by quitting the
  162. > application after plotting a lot of icons (i only needed to see them for a
  163. > while while the app is in development).  a more elegant solution remains 
  164. > a mystery to me
  165.  
  166. Whoops, sorry.  It's DisposCIcon() that you need.  So, GetCIcon(), PlotCIcon(),
  167. DisposCIcon().
  168.  
  169. john calhoun-
  170.  
  171.  
  172. +++++++++++++++++++++++++++
  173.  
  174. From: nextweek@reed.edu!nextweek.Reed.Edu!pcalahan (Patrick John Calahan)
  175. Date: 20 Jul 92 02:38:56 GMT
  176. Organization: Reed College, Portland, OR
  177.  
  178. In article <1992Jul19.010403.41701@kuhub.cc.ukans.edu>  
  179. ozma@kuhub.cc.ukans.edu writes:
  180. > In article <m0m8zd3-0006ChC@gluttony.reed.edu>,  
  181. gluttony@reed.edu!gluttony.reed.edu!pcalahan (Patrick John Calahan)  
  182. writes:
  183. > > In article <1992Jul16.234146.41639@kuhub.cc.ukans.edu>  
  184. > > ozma@kuhub.cc.ukans.edu writes:
  185. > >> I believe ReleaseResource() after every PlotCIcon will do the trick.
  186. > >> john calhoun-
  187. > > 
  188. > > nope. like i said in the message, i had been using release resource  
  189. but
  190. > > it still wasn't working.  i kludged my way around it by quitting the
  191. > > application after plotting a lot of icons (i only needed to see them  
  192. for a
  193. > > while while the app is in development).  a more elegant solution  
  194. remains 
  195. > > a mystery to me
  196. > Whoops, sorry.  It's DisposCIcon() that you need.  So, GetCIcon(),  
  197. PlotCIcon(),
  198. > DisposCIcon().
  199. > john calhoun-
  200. been trying that to...no go :)  no matter to me anymore, though
  201.  
  202. +++++++++++++++++++++++++++
  203.  
  204. From: absurd@applelink.apple.com (Tim Dierks, software saboteur)
  205. Date: 29 Jul 92 00:09:18 GMT
  206. Organization: MacDTS Misfits
  207.  
  208. In article <1992Jul16.234146.41639@kuhub.cc.ukans.edu>,
  209. ozma@kuhub.cc.ukans.edu wrote:
  210. > In article <36915@unix.SRI.COM>, mxmora@unix.SRI.COM (Matt Mora) writes:
  211. > > In article <m0m7vfN-000FO0C@bagpipe.reed.edu> bagpipe@reed.edu!bagpipe.reed.edu!pcalahan (Patrick John Calahan) writes:
  212. > > 
  213. > >>IMV says that you shouldn't call PlotCICon before each GetCIcon because
  214. > >>it overhead will build up in the resource map.  Makes sense to me...that  
  215. > >>seems to be happenening when my system crashes after plotting some number  
  216. > >>of icons...
  217. > > You could mark them purgeable. But I don't think that really works. I think
  218. > > there is a bug with cicns or something because I tried to get rid of the
  219. > > memory but it would still fill up the heap. I'm using ploticonid now
  220. > > (tech note #30x) and it works fine. 
  221. > I believe ReleaseResource() after every PlotCIcon will do the trick.
  222. Actually, the appropriate call is DisposCIcon(), which will dispose of all
  223. the various handles associated with a color icon.  ReleaseResource() would
  224. not release all the handles; in fact, I think it would be in error, because
  225. I'm pretty sure that a CIconHandle in memory is not a resource handle; it's
  226. constructed from one.
  227.  
  228. Tim Dierks
  229. MacDTS, but I speak for the trees
  230.  
  231. ---------------------------
  232.  
  233. From: mar@ocf.berkeley.edu (Michael A. Ramirez)
  234. Subject: Powerbook Battery Question
  235. Date: 21 Jul 92 22:17:25 GMT
  236. Organization: U.C. Berkeley Open Computing Facility
  237.  
  238.  
  239.  
  240. I am wondering how I can get rid of the dialog boxes warning me that the
  241. power is low on the Powerbooks. Are these dialog boxes in the ROM or
  242. in the System file? Any help or comments would be appreciated.
  243.  
  244. Thanks.
  245.  
  246. Michael
  247. - -- 
  248. - -----------------------------------------------------------------------------
  249. ___    _   ___ ___ _  ____  ____  ____   mar@ocf.berkeley.edu
  250. |__|  |_|  |  |  | |  |___| |___    /    When laws are outlawed then only
  251. |  \ |   | |  |  | |  |  \  |___  /___   outlaws will obey the law- Mondo 2000
  252.  
  253. +++++++++++++++++++++++++++
  254.  
  255. From: stevec@Apple.COM (Steve Christensen)
  256. Date: 25 Jul 92 02:30:12 GMT
  257. Organization: Apple Computer Inc., Cupertino, CA
  258.  
  259. mar@ocf.berkeley.edu (Michael A. Ramirez) writes:
  260. >I am wondering how I can get rid of the dialog boxes warning me that the
  261. >power is low on the Powerbooks. Are these dialog boxes in the ROM or
  262. >in the System file? Any help or comments would be appreciated.
  263.  
  264. I assume from your question that you don't mind if your PowerBook will
  265. suddenly go to sleep without notice in order to preserve the state of
  266. its memory (and thus your data)?
  267.  
  268. OK, if so, you can find the strings it uses to warn you in the System File.
  269. If you remove them, you won't get any warnings, the PowerBook will just go
  270. to sleep...
  271.  
  272. steve
  273.  
  274. - -- 
  275. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  276.   Steve Christensen            Never hit a man with glasses.
  277.   stevec@apple.com            Hit him with a baseball bat.
  278.  
  279. ---------------------------
  280.  
  281. From: rla20@duts.ccc.amdahl.com (Roger Allen)
  282. Subject: Quick TCL gDesktop question
  283. Date: 21 Jul 92 21:24:46 GMT
  284. Organization: Amdahl Corporation, Sunnyvale CA
  285.  
  286. Quickie:
  287.  
  288. For multi-monitor systems, does gDesktop->bounds include the main device
  289. only or some rect that bounds all of the screens.
  290.  
  291. In other words is gDesktop->bounds A or B.  Where B is the main screen and
  292. C is another screen and A is the rect that bounds them.
  293.  
  294.    AAAAAAAAAAAAAAAAAAA
  295.    ABBBBBBBB         A
  296.    AB      B         A
  297.    AB  ..  B         A
  298.    AB  \/  BCCCCCCCCCA
  299.    AB      BC       CA
  300.    ABBBBBBBBC       CA
  301.    A        C       CA
  302.    A        C       CA
  303.    A        C       CA
  304.    A        CCCCCCCCCA
  305.    AAAAAAAAAAAAAAAAAAA
  306.  
  307. Hope it takes less time to answer than it did to draw that.
  308.  
  309.  
  310. Roger
  311. - --
  312. > Roger Allen                   |                                        <
  313. > Amdahl Computer Development   | What are you looking here for?         <
  314. > rla20@cd.amdahl.com           |                                        <
  315.  
  316. +++++++++++++++++++++++++++
  317.  
  318. From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
  319. Date: 23 Jul 92 16:45:36 GMT
  320. Organization: Kalamazoo College
  321.  
  322. rla20@DUTS.ccc.amdahl.com (Roger Allen) writes:
  323. >Quickie:
  324. >For multi-monitor systems, does gDesktop->bounds include the main device
  325. >only or some rect that bounds all of the screens.
  326.  
  327. All the screens.
  328.  
  329.  
  330. This is despite the comment in ThC's TCL 1.1's CDesktop::IDesktop:
  331.  
  332.     /* Make the port rectangle coincide with the bounding box of    */
  333.     /* the gray region (entire screen excluding the menu bar). ...    */
  334. grayRgn = GetGrayRgn();
  335. bounds = (**grayRgn).rgnBBox;
  336.  
  337. The parenthetic should read "(all screens excluding the menu bar)".
  338.  
  339.  
  340. >Hope it takes less time to answer than it did to draw that.
  341.  
  342. Probably...  :-)
  343. - -- 
  344.  Jamie McCarthy      Internet: k044477@kzoo.edu      AppleLink: j.mccarthy
  345.  I'm having a lot of trouble seeing how a request that you "shut up" can be
  346.  interpreted as "looking to other people for validation."      - Tim Pierce
  347.  
  348. ---------------------------
  349.  
  350. From: tj@kona.cs.ucla.edu (Tom Johnson)
  351. Subject: Smooth Animation
  352. Date: 23 Jul 92 19:59:03 GMT
  353. Organization: UCLA Computer Science Department
  354.  
  355.  
  356.     FAQ Alert!  FAQ Alert!  FAQ Alert!
  357.  
  358. Could someone send me some sample code for doing smooth color
  359. animation that's compatible with all the different machines and
  360. accelerated/non-accelerated video cards out there?
  361.  
  362. Or some discussion/archived c.s.m.p posts?
  363.  
  364. I've seen so much of this in the past, but since my work never required
  365. any sort of animated graphics, I didn't save anything.  And now.....
  366.  
  367. Now I feel stupid for not saving them.
  368.  
  369. Thanks-
  370.   Tom
  371. - -- 
  372. Tom Johnson             "They say Confucious does his crossword with a pen."
  373. tj@cs.ucla.edu                               -Tori Amos
  374.  
  375. +++++++++++++++++++++++++++
  376.  
  377. From: tj@kona.cs.ucla.edu (Tom Johnson)
  378. Organization: UCLA Computer Science Department
  379. Date: Fri, 31 Jul 92 20:57:37 GMT
  380.  
  381. I'm thinking about writing a game, so I decided I'd play around a bit and
  382. try to get some nice fast and smooth animation running just to see how to
  383. do it.  Nothing fancy, just a box bouncing around in a window on the screen.
  384. I've got the drawing sync'd to a VBL task and everything works great in a 
  385. situation like this:
  386.  
  387.   do {
  388.     DrawNextFrame();
  389.      } while (!Button());
  390.  
  391. of course.  But when I put it into a real event loop:
  392.   do {
  393.     MainIdle();
  394.     gotEvent = WaitNextEvent(everyEvent, &theEvent, 0,nil);
  395.     if (gotEvent)
  396.         HandleEvent(&theEvent);
  397.       } while (gQuitApplication != true);    
  398.  
  399. I get all sorts of little starts/stops/pauses in the animation, as the mac
  400. gives time to background processes.  And it's certainly not acceptable for
  401. a fast arcade-style game.
  402.  
  403. How do other game authors handle it?  Do you not give time to bkgnd processes?
  404. Just let downloads timeout?  Or is there some simple idea that's gone by
  405. me completely?
  406.  
  407.  
  408. Question 2:  I've given up on getting enough speed from CopyBits and have
  409. decided that I'm willing to take a few risks and write directly to the 
  410. screen.  I found the sample code in the FAQ for setting pixels.  Does anyone
  411. have some utility routines they might be willing to share to handle other
  412. tasks?  (ie drawing Icl's, etc...).  
  413.  
  414. This is just a little throw away freeware
  415. game, so I'm trying to get as much done as I can as quickly as possible. Has
  416. anyone ever written a sample arcade game and given away the source? Something
  417. I could base mine upon?
  418.  
  419. Thanks-
  420.   Tom    
  421.  
  422. - -- 
  423. Tom Johnson             "They say Confucious does his crossword with a pen."
  424. tj@cs.ucla.edu                               -Tori Amos
  425.  
  426. +++++++++++++++++++++++++++
  427.  
  428. From: mspace@netcom.com (Brian Hall)
  429. Date: Sat, 01 Aug 92 07:03:09 GMT
  430. Organization: Netcom - Online Communication Services  (408 241-9760 guest) 
  431.  
  432. tj@kona.cs.ucla.edu (Tom Johnson) writes:
  433.  
  434. >I'm thinking about writing a game, so I decided I'd play around a bit and
  435. >try to get some nice fast and smooth animation running just to see how to
  436. >do it.  Nothing fancy, just a box bouncing around in a window on the screen.
  437. >I've got the drawing sync'd to a VBL task and everything works great in a 
  438. >situation like this:
  439.  
  440. >  do {
  441. >    DrawNextFrame();
  442. >     } while (!Button());
  443.  
  444. >of course.  But when I put it into a real event loop:
  445. >  do {
  446. >    MainIdle();
  447. >    gotEvent = WaitNextEvent(everyEvent, &theEvent, 0,nil);
  448. >    if (gotEvent)
  449. >        HandleEvent(&theEvent);
  450. >      } while (gQuitApplication != true);    
  451.  
  452. >I get all sorts of little starts/stops/pauses in the animation, as the mac
  453. >gives time to background processes.  And it's certainly not acceptable for
  454. >a fast arcade-style game.
  455.  
  456. Instead of calling WNE for each pass through the loop, why not try calling
  457. it once every few ticks. Perhaps one call every 10 ticks.  You could
  458. vary the number depending on how friendly you want to be.
  459.  
  460. A friend of mine did this in a database program he was working on where
  461. it called WNE during long processes, and found that by calling WNE once
  462. every so often instead of once per pass, he was able to more than double
  463. the time to sort the database.
  464.  
  465. - -- 
  466.  
  467.  \ | /   | Brian Hall                 mspace@netcom.com
  468.  - : -   | Mark/Space Softworks       Applelink: markspace
  469.   /|\    |                            America Online: MarkSpace
  470.  |-+-|   |
  471. /-\|/-\  | People don't kill people, toasters kill people.
  472.  
  473. ---------------------------
  474.  
  475. From: mmigdol@ccwf.cc.utexas.edu (michael a migdol)
  476. Subject: Using PostHighLevelEvents to send low level (KeyPressed) events
  477. Date: 24 Jul 92 14:31:06 GMT
  478. Organization: The University of Texas at Austin, Austin TX
  479.  
  480. According to IM VI, p. 5-18, "Your application can both send and receive high-
  481. level events, but it generally only receives low-level events and should not
  482. send them."
  483.  
  484. So, this implies that I *can* send KeyPressed events to other applications. 
  485. (Even though I "shouldn't", I want to. I really do! :) )
  486.  
  487. Anyways, Apple certainly doesn't seem to encourage this, and I'm about to try
  488. this out myself, but am I supposed to use PostHighLevelEvents with theEvent.what
  489. set to Keypressed (or whatever) to do this? Am I going to hit any problems 
  490. later on? Does the application I'm sending to have to "AcceptHighLevelEvents"
  491. to receive low level events sent this way?
  492.  
  493. Thanks in advance, and smile - it's FRIDAY!
  494. - -Michael
  495.  
  496. +++++++++++++++++++++++++++
  497.  
  498. From: smoke@well.sf.ca.us (Nicholas Jackiw)
  499. Organization: Whole Earth 'Lectronic Link
  500. Date: Fri, 24 Jul 1992 16:04:10 GMT
  501.  
  502. In article <76508@ut-emx.uucp> mmigdol@ccwf.cc.utexas.edu (michael a migdol) writes:
  503. >According to IM VI, p. 5-18, "Your application can both send and receive high-
  504. >level events, but it generally only receives low-level events and should not
  505. >send them."
  506. >
  507. >So, this implies that I *can* send KeyPressed events to other applications. 
  508. >(Even though I "shouldn't", I want to. I really do! :) )
  509.  
  510. That's right; you can and "shouldn't."  Remember, however, that it's *your*
  511. Macintosh and you can do what you damn well like with it.
  512.  
  513. >
  514. >Anyways, Apple certainly doesn't seem to encourage this, and I'm about to try
  515. >this out myself, but am I supposed to use PostHighLevelEvents with theEvent.what
  516. >set to Keypressed (or whatever) to do this? Am I going to hit any problems 
  517. >later on? Does the application I'm sending to have to "AcceptHighLevelEvents"
  518. >to receive low level events sent this way?
  519.  
  520. No, PostHighLevelEvents won't work for this; all high-level events are of
  521. the same low-level event type.  Nor do you need AcceptHighLevelEvents; this
  522. will simply add unnecessary launch-time overhead.
  523.  
  524. I believe that any low-level event gets sent to the event handler of the
  525. foremost application.  This means you'll need to have your receiver in
  526. front.  (See the Process Manager in System 7 for how to do this automatically,
  527. otherwise just bring it to the front with the multifinder menu after 
  528. launching the sender.)  Then, call PostEvent from your sender with
  529. the appropriate keydowns.  
  530.  
  531. [Actually, I think you should use PPostEvent, which will return to you
  532. a pointer to the event that will be shipped the frontapp. You want this
  533. pointer if you intend to do any preprocessing of the event record, such
  534. as clearing its modifier keys or setting the "where" field to a mouse
  535. location of your choice.]
  536.  
  537.  
  538.  
  539. - -- 
  540.                               --- * ---
  541. Nick Jackiw                  Smoke@well.sf.ca.us   | Jackiw@cs.swarthmore.edu
  542. Key Curriculum Press, Inc.   Applelink:KEY.EDUSOFT | (510) 548-2304
  543.                               --- * ---
  544.  
  545. +++++++++++++++++++++++++++
  546.  
  547. From: walkerj@math.scarolina.edu (Jim Walker)
  548. Date: 24 Jul 92 17:35:37 GMT
  549. Organization: USC  Department of Computer Science
  550.  
  551. To post low-level events, use PPostEvent.  It is documented in IM IV, but
  552. was omitted from the index.  I think it's in the chapter on the OS Event
  553. Manager.  The advantage of PPostEvent over PostEvent is that the former
  554. allows you to set the modifiers, location, and time as well as the message.
  555.  
  556.  
  557. - --
  558.  
  559.  -- Jim Walker  USC Dept. of Math.  walkerj@math.scarolina.edu
  560.  
  561. ---------------------------
  562.  
  563. From: fsmah1@acad3.alaska.edu (Mike Hageland)
  564. Subject: Radio buttons
  565. Date: 27 Jul 92 03:51:45 GMT
  566. Organization: University of Alaska Fairbanks
  567.  
  568. I have a very simple little problem with what seems to be a complicated
  569. solution.  Look at this diagram and pretend the X represents where I
  570. want a radio button.
  571.  
  572.   X  Title | Title X
  573.   X  Title | Title X
  574.   X  Title | Title X
  575.  
  576. Personally I think this looks kinda neat.  I would like to do something
  577. like this.  Now this is no problem, I can simply draw the titles in and 
  578. then place in the radio buttons.  However, then you can't simply click 
  579. onto the title like you can with most radio buttons.  It seems that the
  580. radio button will only put the title to the right of the radio button.  
  581.  
  582. The way I can think of to do this is to create another simple button over the
  583. titles on the right side and deal with changing the radio buttons around
  584. when it is pressed. 
  585.  
  586. Can anybody think of a cleaner way to do this?  Is there a hiden way to
  587. make a radio button have a title on the left?
  588.  
  589. +++++++++++++++++++++++++++
  590.  
  591. From: ericsc@microsoft.com (Eric Schlegel)
  592. Date: 29 Jul 92 19:58:07 GMT
  593. Organization: Microsoft Corporation
  594.  
  595. In article <1992Jul26.195145.1@acad3.alaska.edu> fsmah1@acad3.alaska.edu (Mike Hageland) writes:
  596. >I have a very simple little problem with what seems to be a complicated
  597. >solution.  Look at this diagram and pretend the X represents where I
  598. >want a radio button.
  599. >
  600. >  X  Title | Title X
  601. >  X  Title | Title X
  602. >  X  Title | Title X
  603. >
  604. >Personally I think this looks kinda neat.  I would like to do something
  605. >like this.  Now this is no problem, I can simply draw the titles in and 
  606. >then place in the radio buttons.  However, then you can't simply click 
  607. >onto the title like you can with most radio buttons.  It seems that the
  608. >radio button will only put the title to the right of the radio button.  
  609. >
  610. >Is there a hidden way to make a radio button have a title on the left?
  611.  
  612. You need to set the system justification to teFlushRight (-1) before
  613. drawing the right-hand column of radio buttons. You can do this with the
  614. Script Manager trap _SetSysJust:
  615.     SetSysJust(teFlushRight);
  616. Don't forget to save the previous justification using _GetSysJust before
  617. changing it, and restore it afterwards.
  618.  
  619. If you're doing this in a window of your own creation, you can just 
  620. call _SetSysJust and then _Draw1Control to draw the right-hand radio buttons.
  621. If your radio buttons are in a Dialog Manager dialog you may need to use
  622. a filter proc that catches update events and does the updating itself,
  623. using _SetSysJust and _Draw1Control as needed, instead of letting the Dialog
  624. Manager draw the controls.
  625.  
  626. For more information, see Inside Mac vol. 5, pg. 301, "Writing Direction."
  627.  
  628. - -eric
  629. - -------
  630. My opinions, not Microsoft's.
  631.  
  632. ---------------------------
  633.  
  634. From: kaas@cc.ruu.nl (Dick Kaas)
  635. Subject: menubar in dialogs
  636. Date: 28 Jul 92 13:27:28 GMT
  637. Organization: -
  638.  
  639.  
  640. I'm planning to write a TCL pane for a menu-bar.
  641.  
  642. Is there a simple way to implement a menubar into dialogs  (like WP and
  643. superboomerang) without having to write a complete menu package by
  644. yourself?
  645.  
  646. I have looked at the low memory globals, such as MenuBarHook etc. None of
  647. these seem useful.
  648.  
  649. Dick kaas.
  650.  
  651. +++++++++++++++++++++++++++
  652.  
  653. From: keith@taligent.com (Keith Rollin)
  654. Date: 29 Jul 92 08:17:31 GMT
  655. Organization: Taligent
  656.  
  657. In article <kaas-280792151810@jojo.cc.ruu.nl>, kaas@cc.ruu.nl (Dick Kaas)
  658. writes:
  659. > I'm planning to write a TCL pane for a menu-bar.
  660. > Is there a simple way to implement a menubar into dialogs  (like WP and
  661. > superboomerang) without having to write a complete menu package by
  662. > yourself?
  663. > I have looked at the low memory globals, such as MenuBarHook etc. None of
  664. > these seem useful.
  665. >
  666.  
  667. I did one of these. I wouldn't consider the approach I took to be "simple."
  668. Although I wrote the bulk of it in a couple of nights, they were long nights. I
  669. had to re-implement and wrap up a lot of stuff. My first attempt that tried
  670. setting the origin of the window manager port at strategic times didn't work
  671. because of a bug in System 7.0's background saving and restoring routines.
  672.  
  673. I did it as a control to make it easy for others to use. It's included below.
  674.  
  675. How to use: create a control item in your DITL, and specify the CDEF shown
  676. below. When the user clicks on the item, the dialog manager will call
  677. TrackControl. If you are writing a TCL pane, then call TrackControl yourself.
  678. The control will track the menus and leave the chosen item in contrlValue, so
  679. all you have to do is call GetCtlValue to get the chosen menu item.
  680.  
  681. If you want to manipulate the menubar, use one of the macros starting with a "Z"
  682. included below. Those macros will call the CDEF directly with a custom message
  683. number. Please note that for the CallIt macro to work, the CDEF must be marked
  684. as locked. If you don't want to lock your CDEF, then you'll need a more
  685. elaborate way to call the CDEF than just dereferencing the handle and jumping.
  686. As an example of what you might need, I've included a commented-out function at
  687. the end of this posting that calls the standard MBDF directly.
  688.  
  689. A note: pay no attention to the UseGlobals and DoneWithGlobals stuff. That's for
  690. an MPW package that allows globals in standalone code. If you are using THINK C,
  691. don't worry about it. If you are using MPW, use the techniques shown in Technote
  692. #256.
  693.  
  694. (BTW: as you'll see below, MenubarHook _was_ useful!)
  695.  
  696. As a final note, I found it useful to write a wrapper for the standard MDEF.
  697. Because the below CDEF essentially works by using popup menus, you need to have
  698. fine control over where the popup menus show up. The standard MBDF will try to
  699. position popup menus so that as much of them will appear on the screen as
  700. possible. However, we don't want that with our menubar CDEF; we want to the top
  701. of the menu to be right below the menubar. Therefore, I wrap up the standard
  702. MDEF with one of my own that first calls the standard MDEF, and then checks to
  703. see if the message handled was mPopUpMsg. If so, the top of the menu is adjusted
  704. by executing "menuRect->top = *itemID;".
  705.  
  706. Sorry for the lack of any comments in the source code...
  707.  
  708. - -------------
  709. MenubarCDEF.h
  710. - -------------
  711.  
  712. #ifndef THINK_C
  713. #include <Controls.h>
  714. #endif
  715.  
  716. #define kStayPutMDEF    90
  717.  
  718. #define clearMenuBar    128
  719. #define deleteMenu        129            // param = ID of menu to remove
  720. #define drawMenuBar        130
  721. #define flashMenuBar    131            // param = ID of menu to flash
  722. #define getMenuBar        132            // result = handle to custom data
  723. #define getMHandle        133            // param = menu ID, result = menuHandle
  724. #define hiliteMenu        134            // param = ID of menu to hilite
  725. #define insertMenu        135            // param = menuHandle, varCode = before menu ID
  726. #define menuKey            136            // param = char, result = same as MenuKey
  727. #define menuSelect        137            // param = startPt, result = same as MenuSelect
  728. #define setMenuBar        138            // param = result from getMenuBar
  729.  
  730. typedef pascal long (*CDEFProc)(short varCode, ControlHandle theControl,
  731.                                     short msg, long param);
  732.  
  733. #define CallIt(ctl) ((CDEFProc) *((**ctl).contrlDefProc))
  734.  
  735. #define ZClearMenuBar(ctl)            CallIt(ctl)(0, ctl, clearMenuBar, 0)
  736. #define ZDeleteMenu(ctl, menuID)    CallIt(ctl)(0, ctl, deleteMenu, menuID)
  737. #define ZDrawMenuBar(ctl)            CallIt(ctl)(0, ctl, drawMenuBar, 0)
  738. #define ZFlashMenuBar(ctl, menuID)    CallIt(ctl)(0, ctl, flashMenuBar, menuID)
  739. #define ZGetMenuBar(ctl)            (Handle) CallIt(ctl)(0, ctl, getMenuBar, 0)
  740. #define ZGetMHandle(ctl, menuID)    (MenuHandle) CallIt(ctl)(0, ctl, getMHandle,
  741. menuID)
  742. #define ZHiliteMenu(ctl, menuID)    CallIt(ctl)(0, ctl, hiliteMenu, 0)
  743. #define ZInsertMenu(ctl, mh, id)    CallIt(ctl)(id, ctl, insertMenu, mh)
  744. #define ZMenuKey(ctl, key)            CallIt(ctl)(0, ctl, menuKey, key)
  745. #define ZMenuSelect(ctl, startPt)    CallIt(ctl)(0, ctl, menuSelect, startPt)
  746. #define ZSetMenuBar(ctl, mbar)        CallIt(ctl)(0, ctl, setMenuBar, mbar)
  747.  
  748.  
  749.  
  750. - -------------
  751. MenubarCDEF.c
  752. - -------------
  753.  
  754.  
  755. /*
  756.     To do:
  757.     
  758.     % Support hierarchicals
  759.     % Support color
  760. */
  761.  
  762. #include "MetaGlobal.h"
  763. #include "MenubarCDEF.h"
  764.  
  765. #ifdef THINK_C
  766.     #include <SetUpA4.h>
  767.     Ptr GetA0(void) = { 0x2008 };
  768. #else
  769.     #include <Types.h>
  770.     #include <Memory.h>
  771.     #include <Menus.h>
  772.     #include <OSEvents.h>            // For EvQPtr
  773.     #include <Resources.h>            // For GetResource
  774.     #include <Script.h>                // For GetMBarHeight
  775.     #include <ToolUtils.h>            // For HiWord, LoWord
  776.     #include <Windows.h>            // we return inMenubar as our part
  777.     #include "SAGlobals.h"
  778.     
  779.     #define MenuHook (*(ProcPtr*) 0xA30)
  780.     #define MenuList (*(Handle*) 0xA1C)
  781. #endif
  782.  
  783. #define NIL                NULL
  784. #define kTopMargin        1
  785. #define kBottomMargin    1
  786. #define kTextMargin        8
  787.  
  788.  
  789. typedef struct {
  790.     MenuHandle        menu;
  791.     short            menuLeft;
  792. } MenuRec, *MenuRecPtr;
  793.  
  794.  
  795. typedef struct {
  796.     MenuHandle        menu;
  797.     short            reserved;
  798. } HMenuRec, *HMenuRecPtr;
  799.  
  800.  
  801. typedef struct {
  802.     short            lastMenu;
  803.     short            lastRight;
  804.     short            mbResID;
  805.     MenuRec            menus[1];
  806.     //    short            lastHMenu;
  807.     //    PixMapHandle    menuTitleSave;
  808.     //    MenuRec            hmenus[1];
  809. } MenuBar, *MenuBarPtr, **MenuBarHdl;
  810.  
  811.  
  812. ProcPtr            gOldMenuHook;
  813. ControlHandle    gControl;
  814. MenuBarHdl        gMenuList;
  815. short            gTheMenu;            // _Index_ of currently hilighted menu
  816. short            gNormalHeight;
  817. FontInfo        gFontInfo;
  818. short            gBaseline;
  819.  
  820.  
  821. pascal long        main(short varCode, ControlHandle theControl, short msg, long
  822. param);
  823.  
  824. void            DrawMyControl(short part);
  825. short            TestMyControl(Point location);
  826. void            InitMyControl(void);
  827. void            DisposeMyControl(void);
  828.  
  829. void            DoClearMenuBar(void);
  830. void            DoDeleteMenu(short menuID);
  831. void            DoDrawMenuBar(void);
  832. void            DoFlashMenuBar(short menuID);
  833. MenuBarHdl        DoGetMenuBar(void);
  834. MenuHandle        DoGetMHandle(short menuID);
  835. void            DoHiliteMenu(short menuID);
  836. void            DoInsertMenu(MenuHandle menu, short before);
  837. long            DoMenuKey(char theKey);
  838. long            DoMenuSelect(Point startPt);
  839. void            DoSetMenuBar(MenuBarHdl menuBar);
  840.  
  841. void            DrawMenuTitle(short menuIndex);
  842. short            FindHitMenu(Point location);        // returns menuIndex (or -1)
  843. short            GetFreeHMenuID(void);
  844. Rect            GetHitRect(short menuIndex);
  845. Rect            GetInvertRect(short menuIndex);
  846. short            GetMenuCount(void);
  847. MenuHandle        GetNthMenu(short index);
  848. Point            GetTitleLocation(short menuIndex);
  849. short            IDToIndex(short);
  850. short            IndexToID(short);
  851. void            MyMenuHook(void);
  852. void            SwapMenuBars(void);
  853.  
  854. //--------------------------------------------------------------------------------
  855.  
  856. pascal long    main(short varCode, ControlHandle theControl, short msg, long param)
  857. {
  858.     long        result;
  859.     Ptr            oldA5;
  860.     char        oldState;
  861.     Handle        ourHandle;
  862.     Ptr            ourPtr;
  863.  
  864.     ourPtr = GetA0();
  865.  
  866. #ifdef THINK_C
  867.     RememberA0();
  868.     SetUpA4();
  869. #else
  870.     oldA5 = UseGlobals();
  871. #endif
  872.  
  873.     ourHandle = RecoverHandle(ourPtr);
  874.     oldState = HGetState(ourHandle);
  875.     HLock(ourHandle);
  876.     
  877.     result = 0;
  878.     gControl = theControl;
  879.     GetFontInfo(&gFontInfo);
  880.     gBaseline = kTopMargin + gFontInfo.leading + gFontInfo.ascent;
  881.  
  882.     if (msg < 128) {
  883.         switch (msg) {
  884.             case drawCntl:
  885.                 DrawMyControl((short) param);
  886.                 break;
  887.             case testCntl:
  888.                 result = TestMyControl(*(Point*) ¶m);
  889.                 break;
  890.             case initCntl:
  891.                 InitMyControl();
  892.                 break;
  893.             case dispCntl:
  894.                 DisposeMyControl();
  895.                 break;
  896.             case calcCntlRgn:
  897.             case calcThumbRgn:
  898.                 RectRgn((RgnHandle) param, &(**gControl).contrlRect);
  899.                 result = 1;
  900.                 break;
  901.         }
  902.     } else {
  903.         switch (msg) {
  904.             case clearMenuBar:
  905.                 DoClearMenuBar();
  906.                 break;
  907.             case deleteMenu:
  908.                 DoDeleteMenu((short) param);
  909.                 break;
  910.             case drawMenuBar:
  911.                 DoDrawMenuBar();
  912.                 break;
  913.             case flashMenuBar:
  914.                 DoFlashMenuBar((short) param);
  915.                 break;
  916.             case getMenuBar:
  917.                 result = (long) DoGetMenuBar();
  918.                 break;
  919.             case getMHandle:
  920.                 result = (long) DoGetMHandle((short) param);
  921.                 break;
  922.             case hiliteMenu:
  923.                 DoHiliteMenu((short) param);
  924.                 break;
  925.             case insertMenu:
  926.                 DoInsertMenu((MenuHandle) param, varCode);
  927.                 break;
  928.             case menuKey:
  929.                 result = DoMenuKey((char) param);
  930.                 break;
  931.             case menuSelect:
  932.                 result = DoMenuSelect(*(Point*) ¶m);
  933.                 break;
  934.             case setMenuBar:
  935.                 DoSetMenuBar((MenuBarHdl) param);
  936.                 break;
  937.         }
  938.     }
  939.  
  940. #ifdef THINK_C
  941.     RestoreA4();
  942. #else
  943.     DoneWithGlobals(oldA5);
  944. #endif
  945.     
  946.     HSetState(ourHandle, oldState);
  947.  
  948.     return result;
  949. }
  950.  
  951.  
  952. //--------------------------------------------------------------------------------
  953.  
  954. void    DrawMyControl(short part)
  955. {
  956. #pragma unused (part)
  957.  
  958.     if ((**gControl).contrlVis != false) {
  959.         DoDrawMenuBar();
  960.     }
  961. }
  962.  
  963.  
  964. //--------------------------------------------------------------------------------
  965.  
  966. short    TestMyControl(Point location)
  967. {
  968.     short        hitPart;
  969.     
  970.     hitPart = 0;
  971.     if (FindHitMenu(location) >= 0) {
  972.         hitPart = inMenuBar;
  973.         if (Button()) {
  974.             DoMenuSelect(location);
  975.             if ((**gControl).contrlValue == 0) {
  976.                 hitPart = 0;
  977.             }
  978.         }
  979.     }
  980.  
  981.     return hitPart;
  982. }
  983.  
  984.  
  985. //--------------------------------------------------------------------------------
  986.  
  987. void    InitMyControl()
  988. {
  989.     Handle        menuBar;
  990.  
  991.     gOldMenuHook = NIL;
  992.     gMenuList = NIL;
  993.     gTheMenu = -1;
  994.     gNormalHeight = GetMBarHeight();
  995.     (**gControl).contrlRect.bottom = (**gControl).contrlRect.top + gBaseline
  996.                         + gFontInfo.descent + gFontInfo.leading + kBottomMargin;
  997.  
  998.     GetMBarHeight() = 0;
  999.     menuBar = GetNewMBar((**gControl).contrlMin);
  1000.     if (menuBar != NIL) {
  1001.         gMenuList = (MenuBarHdl) menuBar;
  1002.     } else {
  1003.         menuBar = GetMenuBar();
  1004.         ClearMenuBar();
  1005.         gMenuList = (MenuBarHdl) GetMenuBar();
  1006.         SetMenuBar(menuBar);
  1007.         DisposeHandle(menuBar);
  1008.     }
  1009.     GetMBarHeight() = gNormalHeight;
  1010. }
  1011.  
  1012.  
  1013. //--------------------------------------------------------------------------------
  1014.  
  1015. void    DisposeMyControl()
  1016. {
  1017.     DisposeHandle((Handle) gMenuList);
  1018. }
  1019.  
  1020.  
  1021. //--------------------------------------------------------------------------------
  1022.  
  1023. void    DoClearMenuBar()
  1024. {
  1025.     SwapMenuBars();
  1026.     ClearMenuBar();
  1027.     SwapMenuBars();
  1028. }
  1029.  
  1030.  
  1031. //--------------------------------------------------------------------------------
  1032.  
  1033. void    DoDeleteMenu(short menuID)
  1034. {
  1035.     if (IndexToID(gTheMenu) == menuID)
  1036.         gTheMenu = -1;
  1037.  
  1038.     SwapMenuBars();
  1039.     DeleteMenu(menuID);
  1040.     SwapMenuBars();
  1041. }
  1042.  
  1043.  
  1044. //--------------------------------------------------------------------------------
  1045.  
  1046. void    DoDrawMenuBar()
  1047. {
  1048.     Rect            frame;
  1049.     short            loop;
  1050.  
  1051.     PenNormal();
  1052.     frame = (**gControl).contrlRect;
  1053.     FrameRect(&frame);
  1054.  
  1055.     gTheMenu = -1;
  1056.     for (loop = GetMenuCount() - 1; loop >= 0; loop--) {
  1057.         DrawMenuTitle(loop);
  1058.     }
  1059. }
  1060.  
  1061.  
  1062. //--------------------------------------------------------------------------------
  1063.  
  1064. void    DoFlashMenuBar(short menuID)
  1065. {
  1066.     Rect        bounds;
  1067.  
  1068.     if (menuID != 0)
  1069.         DoHiliteMenu(menuID);
  1070.     else {
  1071.         bounds = (**gControl).contrlRect;
  1072.         InsetRect(&bounds, 1, 1);
  1073.         InvertRect(&bounds);
  1074.     }
  1075. }
  1076.  
  1077.  
  1078. //--------------------------------------------------------------------------------
  1079.  
  1080. MenuBarHdl    DoGetMenuBar()
  1081. {
  1082.     return gMenuList;
  1083. }
  1084.  
  1085.  
  1086. //--------------------------------------------------------------------------------
  1087.  
  1088. MenuHandle    DoGetMHandle(short menuID)
  1089. {
  1090.     short    menuIndex;
  1091.     
  1092.     menuIndex = IDToIndex(menuID);
  1093.     if (menuIndex >= 0)
  1094.         return GetNthMenu(menuIndex);
  1095.     else
  1096.         return NIL;
  1097. }
  1098.  
  1099.  
  1100. //--------------------------------------------------------------------------------
  1101.  
  1102. void    DoHiliteMenu(short menuID)
  1103. {
  1104.     short        menuIndex;
  1105.     Rect        invertRect;
  1106.     
  1107.     menuIndex = IDToIndex(menuID);
  1108.     if (menuIndex != gTheMenu) {
  1109.         if (menuIndex >= 0) {
  1110.             invertRect = GetInvertRect(menuIndex);
  1111.             InvertRect(&invertRect);
  1112.         }
  1113.         gTheMenu = menuIndex;
  1114.     }
  1115. }
  1116.  
  1117.  
  1118. //--------------------------------------------------------------------------------
  1119.  
  1120. void    DoInsertMenu(MenuHandle menu, short before)
  1121. {
  1122.     SwapMenuBars();
  1123.     InsertMenu(menu, before);
  1124.     SwapMenuBars();
  1125. }
  1126.  
  1127.  
  1128. //--------------------------------------------------------------------------------
  1129.  
  1130. long    DoMenuKey(char theKey)
  1131. {
  1132.     char            upperKey[2];
  1133.     short            loop;
  1134.     MenuHandle        menu;
  1135.     short            mItems;
  1136.     short            menuItem;
  1137.     short            key;
  1138.  
  1139.     upperKey[0] = 1;
  1140.     upperKey[1] = theKey;
  1141.     UprString((StringPtr) &upperKey, true);
  1142.  
  1143.     for (loop = GetMenuCount() - 1; loop >= 0; loop--) {
  1144.         menu = GetNthMenu(loop);
  1145.         mItems = CountMItems(menu);
  1146.         for (menuItem = 1; menuItem <= mItems; menuItem++) {
  1147.             if (menuItem > 31 || (((**menu).enableFlags & (1 << menuItem)) != 0)) {
  1148.                 GetItemCmd(menu, menuItem, &key);
  1149.                 if (key == upperKey[1]) {
  1150.                     return ((long) (**menu).menuID << 16) + menuItem;
  1151.                 }
  1152.             }
  1153.         }
  1154.     }
  1155.  
  1156.     return 0;
  1157. }
  1158.  
  1159.  
  1160. //--------------------------------------------------------------------------------
  1161.  
  1162. long    DoMenuSelect(Point startPt)
  1163. {
  1164. #pragma unused (startPt)
  1165.  
  1166.     Point            currentLocation;
  1167.     short            oldMenuIndex;
  1168.     short            newMenuIndex;
  1169.     Rect            invertRect;
  1170.     Point            where;
  1171.     MenuHandle        menu;
  1172.     long            menuAndItem;
  1173.     short            oldMenuID;
  1174.     Handle            myMDEF;
  1175.  
  1176.     menuAndItem = 0;
  1177.     while (Button()) {
  1178.         GetMouse(¤tLocation);
  1179.         oldMenuIndex = gTheMenu;
  1180.         newMenuIndex = FindHitMenu(currentLocation);
  1181.         if (oldMenuIndex != newMenuIndex) {
  1182.             gTheMenu = newMenuIndex;
  1183.             DrawMenuTitle(oldMenuIndex);
  1184.             if (newMenuIndex >= 0) {
  1185.                 DrawMenuTitle(newMenuIndex);
  1186.     
  1187.                 invertRect = GetInvertRect(newMenuIndex);
  1188.                 where.v = invertRect.bottom + 1;
  1189.                 where.h = invertRect.left + 1;
  1190.                 LocalToGlobal(&where);
  1191.     
  1192.                 gOldMenuHook = MenuHook;
  1193.                 MenuHook = (ProcPtr) MyMenuHook;
  1194.     
  1195.                 menu = GetNthMenu(newMenuIndex);
  1196.     
  1197.                 oldMenuID = (**menu).menuID;
  1198.                 (**menu).menuID = GetFreeHMenuID();
  1199.     
  1200.                 myMDEF = GetResource('MDEF', kStayPutMDEF);
  1201.                 if (myMDEF != NIL) {
  1202.                     (**(StdHeaderHdl) myMDEF).refCon = (long) (**menu).menuProc;
  1203.                     (**menu).menuProc = myMDEF;
  1204.                 }
  1205.     
  1206.                 InsertMenu(menu, hierMenu);
  1207.                 menuAndItem = PopUpMenuSelect(menu, where.v, where.h, 1);
  1208.                 DeleteMenu((**menu).menuID);
  1209.     
  1210.                 (**menu).menuID = oldMenuID;
  1211.     
  1212.                 if (myMDEF != NIL) {
  1213.                     (**menu).menuProc = (Handle) (**(StdHeaderHdl) myMDEF).refCon;
  1214.                     (**(StdHeaderHdl) myMDEF).refCon = (long) NIL;
  1215.                 }
  1216.     
  1217.                 MenuHook = gOldMenuHook;
  1218.     
  1219.                 if (HiWord(menuAndItem) != 0)
  1220.                     menuAndItem = ((long) oldMenuID << 16) + (short) menuAndItem;
  1221.     
  1222.                 (**gControl).contrlValue = HiWord(menuAndItem);
  1223.                 (**gControl).contrlMax = LoWord(menuAndItem);
  1224.             }
  1225.         }
  1226.     }
  1227.  
  1228.     if (gTheMenu != -1) {
  1229.         oldMenuIndex = gTheMenu;
  1230.         gTheMenu = -1;
  1231.         DrawMenuTitle(oldMenuIndex);
  1232.     }
  1233.  
  1234.     return menuAndItem;
  1235. }
  1236.  
  1237.  
  1238. //--------------------------------------------------------------------------------
  1239.  
  1240. void    DoSetMenuBar(MenuBarHdl menuBar)
  1241. {
  1242.     DisposeHandle((Handle) gMenuList);
  1243.     gMenuList = menuBar;
  1244.     DoDrawMenuBar();
  1245. }
  1246.  
  1247.  
  1248. //--------------------------------------------------------------------------------
  1249.  
  1250. void    DrawMenuTitle(short menuIndex)
  1251. {
  1252.     Rect            invertRect;
  1253.     Point            titleLocation;
  1254.     MenuHandle        menu;
  1255.  
  1256.     if ((menuIndex >= 0) && (menuIndex < GetMenuCount())) {
  1257.  
  1258.         invertRect = GetInvertRect(menuIndex);
  1259.         EraseRect(&invertRect);
  1260.  
  1261.         menu = GetNthMenu(menuIndex);
  1262.         if ((((**menu).enableFlags & 1) == 0) || ((**gControl).contrlHilite == 255))
  1263.             TextMode(grayishTextOr);
  1264.         else
  1265.             TextMode(srcOr);
  1266.         
  1267.         titleLocation = GetTitleLocation(menuIndex);
  1268.         MoveTo(titleLocation.h, titleLocation.v);
  1269.         HLock((Handle) menu);
  1270.         DrawString((**menu).menuData);
  1271.         HUnlock((Handle) menu);
  1272.  
  1273.         if (gTheMenu == menuIndex)
  1274.             InvertRect(&invertRect);
  1275.     }
  1276. }
  1277.  
  1278.  
  1279. //--------------------------------------------------------------------------------
  1280.  
  1281. short    FindHitMenu(Point location)
  1282. {
  1283.     short            loop;
  1284.     Rect            hitRect;
  1285.  
  1286.     for (loop = GetMenuCount() - 1; loop >= 0; loop--) {
  1287.         hitRect = GetHitRect(loop);
  1288.         if (PtInRect(location, &hitRect)) {
  1289.             break;
  1290.         }
  1291.     }
  1292.  
  1293.     return loop;        // returns -1 if no hit
  1294. }
  1295.  
  1296.  
  1297. //--------------------------------------------------------------------------------
  1298.  
  1299. short    GetFreeHMenuID(void)
  1300. {
  1301.     short    index;
  1302.  
  1303.     for (index = 235-20; index > 0; index--) {
  1304.         if (GetMHandle(index) == NIL)
  1305.             return index;
  1306.     }
  1307.     return -1;
  1308. }
  1309.  
  1310.  
  1311. //--------------------------------------------------------------------------------
  1312.  
  1313. Rect    GetHitRect(short menuIndex)
  1314. {
  1315.     Rect        bounds;
  1316.     RectPtr        rectPtr;
  1317.     MenuBarPtr    menuBarPtr;
  1318.     
  1319.     rectPtr = &(**gControl).contrlRect;
  1320.     menuBarPtr = *gMenuList;
  1321.  
  1322.     bounds.top = rectPtr->top + 1;
  1323.     bounds.bottom = rectPtr->bottom - 1;
  1324.     bounds.left = rectPtr->left + menuBarPtr->menus[menuIndex].menuLeft;
  1325.     menuIndex++;
  1326.     bounds.right = rectPtr->left + ((menuIndex < GetMenuCount())
  1327.                                         ? menuBarPtr->menus[menuIndex].menuLeft
  1328.                                         : menuBarPtr->lastRight);
  1329.     
  1330.     return bounds;
  1331. }
  1332.  
  1333.  
  1334. //--------------------------------------------------------------------------------
  1335.  
  1336. Rect    GetInvertRect(short menuIndex)
  1337. {
  1338.     Rect        bounds;
  1339.     
  1340.     bounds = GetHitRect(menuIndex);
  1341.     bounds.left--;
  1342.     bounds.right += 4;
  1343.     return bounds;
  1344. }
  1345.  
  1346.  
  1347. //--------------------------------------------------------------------------------
  1348.  
  1349. short    GetMenuCount()
  1350. {
  1351.     return (**gMenuList).lastMenu / (short) sizeof(MenuRec);
  1352. }
  1353.  
  1354.  
  1355. //--------------------------------------------------------------------------------
  1356.  
  1357. MenuHandle    GetNthMenu(short index)
  1358. {
  1359.     return (**gMenuList).menus[index].menu;
  1360. }
  1361.  
  1362.  
  1363. //--------------------------------------------------------------------------------
  1364.  
  1365. Point    GetTitleLocation(short menuIndex)
  1366. {
  1367.     Point    result;
  1368.     
  1369.     result.h = (**gMenuList).menus[menuIndex].menuLeft + kTextMargin;
  1370.     result.v = (**gControl).contrlRect.top + gBaseline;
  1371.     
  1372.     return result;
  1373. }
  1374.  
  1375.  
  1376. //--------------------------------------------------------------------------------
  1377.  
  1378. short    IDToIndex(short menuID)
  1379. {
  1380.     short        loop;
  1381.  
  1382.     for (loop = GetMenuCount() - 1; loop >= 0; loop--) {
  1383.         if ((**GetNthMenu(loop)).menuID == menuID)
  1384.             break;
  1385.     }
  1386.     return loop;
  1387. }
  1388.  
  1389.  
  1390. //--------------------------------------------------------------------------------
  1391.  
  1392. short    IndexToID(short menuIndex)
  1393. {
  1394.     if ((menuIndex >= 0) && (menuIndex < GetMenuCount()))
  1395.         return (**GetNthMenu(menuIndex)).menuID;
  1396.     else
  1397.         return 0;
  1398. }
  1399.  
  1400.  
  1401. //--------------------------------------------------------------------------------
  1402.  
  1403. void    MyMenuHook()
  1404. {
  1405.     typedef void (*MenuHookProc)(void);
  1406.  
  1407.     GrafPtr        oldPort;
  1408.     Point        mouseLocation;
  1409.     short        hitMenu;
  1410.     Ptr            oldA5;
  1411.  
  1412. #ifdef THINK_C
  1413.     SetUpA4();
  1414. #else
  1415.     oldA5 = UseGlobals();
  1416. #endif
  1417.  
  1418.     if (gOldMenuHook != NIL)
  1419.         ((MenuHookProc) gOldMenuHook)();
  1420.  
  1421.     GetPort(&oldPort);
  1422.     SetPort((**gControl).contrlOwner);
  1423.     GetMouse(&mouseLocation);
  1424.     hitMenu = FindHitMenu(mouseLocation);
  1425.     if ((hitMenu >= 0) && (hitMenu != gTheMenu)) {
  1426.         PostEvent(mouseUp, 0);
  1427.     }
  1428.     SetPort(oldPort);
  1429.  
  1430. #ifdef THINK_C
  1431.     RestoreA4();
  1432. #else
  1433.     DoneWithGlobals(oldA5);
  1434. #endif
  1435. }
  1436.  
  1437.  
  1438. //--------------------------------------------------------------------------------
  1439.  
  1440. void    SwapMenuBars()
  1441. {
  1442.     MenuBarHdl        oldMenuBar;
  1443.     
  1444.     oldMenuBar = (MenuBarHdl) MenuList;
  1445.     MenuList = (Handle) gMenuList;
  1446.     gMenuList = oldMenuBar;
  1447. }
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453. #if 0
  1454.  
  1455. void            CalcMenuPositions(short index);
  1456. long            CallMBDF(short message, short param1, long param2);
  1457.  
  1458. //--------------------------------------------------------------------------------
  1459.  
  1460. void    CalcMenuPositions(short index)
  1461. {
  1462.     SwapMenuBars();
  1463.     CallMBDF(2, 0, (index+1) * 6);
  1464.     SwapMenuBars();
  1465. }
  1466.  
  1467.  
  1468. //--------------------------------------------------------------------------------
  1469.  
  1470. long    CallMBDF(short message, short param1, long param2)
  1471. {
  1472.     typedef pascal long (*MBDFProc)(short selector, short message, short
  1473. parameter1,
  1474.                                         long parameter2);
  1475.     Handle        mbdfHandle;
  1476.     short        mbResID;
  1477.     short        resID;
  1478.     short        mbVariant;
  1479.     char        oldState;
  1480.     long        result;
  1481.     
  1482.     mbResID = (**gMenuList).mbResID;
  1483.     resID = mbResID >> 3;
  1484.     mbVariant = mbResID & 0x0007;
  1485.     mbdfHandle = GetResource('MBDF', resID);
  1486.     if (mbdfHandle != NIL) {
  1487.         if (*mbdfHandle == NIL)  {
  1488.             LoadResource(mbdfHandle);
  1489.         }
  1490.         if (*mbdfHandle != NIL) {
  1491.         
  1492.             oldState = HGetState(mbdfHandle);
  1493.             HLock(mbdfHandle);
  1494.             result = ((MBDFProc) *mbdfHandle)(mbVariant, message, param1, param2);
  1495.             HSetState(mbdfHandle, oldState);
  1496.             return result;
  1497.         }
  1498.     }
  1499.  
  1500.     SysError(dsMBarNFnd);
  1501. }
  1502. #endif
  1503.  
  1504.  
  1505. - --
  1506. Keith Rollin
  1507. Phantom Programmer
  1508. Taligent, Inc.
  1509.  
  1510. ---------------------------
  1511.  
  1512. End of C.S.M.P. Digest
  1513. **********************
  1514.